package com.ajaxw.main;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction;

import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.util.Version;

import com.ajaxw.constant.DIR;
import com.ajaxw.database.DBAccess;
import com.ajaxw.ds.DocList;
import com.ajaxw.dump.DumpDict;
import com.ajaxw.dump.DumpIdx;

public class Main {
	public static void main(String[] args) throws IOException, SQLException,
			ClassNotFoundException {
		// DumpDict dd = new DumpDict();
		// dd.dump2screen("d:\\workspace\\data\\idx");

		// DumpIdx di = new DumpIdx();
		// // di.dump2screen("d:\\workspace\\data\\dat");
		// dump2file("d:\\workspace\\data\\dat", "d:\\workspace\\data\\idx",
		// "d:\\workspace\\data\\dat_statistic");

		// dumpIdx2file(DIR.DATA + "dat");
		// getMetric("d:\\workspace\\data\\dat");
		// refineData("d:\\workspace\\data\\dat",
		// "d:\\workspace\\data\\dat.ref");
		// 48457

		// constructInvtLst(DIR.DATA + "idx", DIR.DATA + "dat");
		// showPos(DIR.DATA + "pos.dat");

		// test(DIR.DATA + "idx.dat");
		// constructQuery();
		showQuery();
		System.out.println("--------------------------------");
	}

	public static void dump2file(String ff, String ff2, String f2)
			throws IOException {
		FileInputStream fis = new FileInputStream(ff);
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		FileInputStream fis2 = new FileInputStream(ff2);
		BufferedInputStream bis2 = new BufferedInputStream(fis2);
		DataInputStream dis2 = new DataInputStream(bis2);

		FileOutputStream fos = new FileOutputStream(f2);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		Writer dos = new OutputStreamWriter(bos);

		int lstNum = dis.readInt();
		int idxNum = dis2.readInt();

		if (lstNum != idxNum)
			System.out.println("------");

		for (int i = 0; i < lstNum; i++) {
			int len = dis.readInt();
			// for (int j = 0; j < len; j++) {
			// dis.readInt();
			// }
			dis.skipBytes(Integer.SIZE / Byte.SIZE * len);

			dis2.readInt();
			int len2 = dis2.readInt();
			byte[] bytes = new byte[len2];
			dis2.read(bytes);

			dos.write(new String(bytes, "UTF-8") + "," + len + "\n");
		}

		dis.close();
		dis2.close();
		dos.close();
	}

	public static void dumpIdx2file(String ff) throws IOException {
		FileInputStream fis = new FileInputStream(ff);
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		int lstNum = dis.readInt();
		int width = 321;
		int height = 381;
		int arr[][] = new int[height][width];
		int yscal = 1000;
		int xscal = 1000;

		for (int i = 0; i < lstNum; i++) {
			int len = dis.readInt();
			for (int j = 0; j < len; j++) {
				int did = dis.readInt();
				int x = did / xscal;
				int y = j / yscal;
				arr[x][y] = 1;
			}
		}

		dis.close();

		File file = new File(DIR.DATA
				+ Calendar.getInstance().getTimeInMillis() + ".bmp");

		BufferedImage bi = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = (Graphics2D) bi.getGraphics();
		g2.setRenderingHint(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);

		g2.setBackground(Color.WHITE);
		g2.clearRect(0, 0, width, height);
		g2.setPaint(Color.BLACK);

		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				if (arr[i][j] == 1)
					g2.fillRect(j, height - i, 1, 1);
			}
		}

		ImageIO.write(bi, "bmp", file);
	}

	public static void getMetric(String ff) throws IOException {
		FileInputStream fis = new FileInputStream(ff);
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		int lstNum = dis.readInt();
		int maxLen = -1;
		int maxDid = -1;

		for (int i = 0; i < lstNum; i++) {
			int len = dis.readInt();
			if (len > maxLen)
				maxLen = len;
			for (int j = 0; j < len; j++) {
				int did = dis.readInt();
				if (maxDid < did)
					maxDid = did;
			}
		}

		dis.close();

		System.out.println("maxLen: " + maxLen);
		System.out.println("maxDid: " + maxDid);
	}

	public static void refineData(String ff, String f2) throws IOException {
		FileInputStream fis = new FileInputStream(ff);
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		FileOutputStream fos = new FileOutputStream(f2);
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		DataOutputStream dos = new DataOutputStream(bos);

		int lstNum = dis.readInt();
		int left = 0;
		dos.writeInt(lstNum);
		for (int i = 0; i < lstNum; i++) {
			int len = dis.readInt();
			// for (int j = 0; j < len; j++) {
			// dis.readInt();
			// }
			if (len < 100)
				dis.skipBytes(Integer.SIZE / Byte.SIZE * len);
			else {
				dos.writeInt(len);
				for (int j = 0; j < len; j++) {
					dos.writeInt(dis.readInt());
				}
				left++;
			}
		}

		dis.close();
		dos.close();

		System.out.println(left);
	}

	public static void constructInvtLst(String idx, String dat)
			throws IOException {
		FileInputStream idxfis = new FileInputStream(idx);
		BufferedInputStream idxbis = new BufferedInputStream(idxfis);
		DataInputStream idxdis = new DataInputStream(idxbis);

		FileInputStream datfis = new FileInputStream(dat);
		BufferedInputStream datbis = new BufferedInputStream(datfis);
		DataInputStream datdis = new DataInputStream(datbis);

		FileOutputStream idxfos = new FileOutputStream(DIR.DATA + "idx.dat");
		BufferedOutputStream idxbos = new BufferedOutputStream(idxfos);
		DataOutputStream idxdos = new DataOutputStream(idxbos);

		FileOutputStream idxfos2 = new FileOutputStream(DIR.DATA + "pos.dat");
		BufferedOutputStream idxbos2 = new BufferedOutputStream(idxfos2);
		DataOutputStream idxdos2 = new DataOutputStream(idxbos2);

		FileOutputStream datfos = new FileOutputStream(DIR.DATA + "dat.dat");
		BufferedOutputStream datbos = new BufferedOutputStream(datfos);
		DataOutputStream datdos = new DataOutputStream(datbos);

		int datlen = datdis.readInt();
		int idxlen = idxdis.readInt();

		if (datlen != idxlen) {
			System.out.println("not equal");
			return;
		}

		int pos = -1;
		int off = 0;
		while (true) {
			pos++;
			int len;
			try {
				len = datdis.readInt();
			} catch (EOFException eof) {
				break;
			}
			if (len < 10)
				datdis.skipBytes(len * Integer.SIZE / Byte.SIZE);
			else {
				idxdos2.writeInt(pos);

				idxdos.writeInt(len);
				idxdos.writeInt(off);
				off += len;

				for (int i = 0; i < len; i++) {
					datdos.writeInt(datdis.readInt());
				}
			}
		}

		idxdis.close();
		idxdos.close();
		idxdos2.close();
		datdis.close();
		datdos.close();
	}

	public static void showPos(String pos) throws IOException {
		FileInputStream idxfis = new FileInputStream(pos);
		BufferedInputStream idxbis = new BufferedInputStream(idxfis);
		DataInputStream idxdis = new DataInputStream(idxbis);

		int idx = 0;
		while (true) {
			int p;
			try {
				p = idxdis.readInt();
			} catch (EOFException eof) {
				break;
			}

			System.out.println("" + idx++ + ": " + p);
		}

		idxdis.close();
	}

	public static void test(String idx) throws IOException {
		FileInputStream idxfis = new FileInputStream(idx);
		BufferedInputStream idxbis = new BufferedInputStream(idxfis);
		DataInputStream idxdis = new DataInputStream(idxbis);

		int len = -1;
		int off = -1;
		while (true) {

			try {
				len = idxdis.readInt();
				off = idxdis.readInt();
			} catch (EOFException eof) {
				break;
			}
		}

		System.out.println("len: " + len);
		System.out.println("off: " + off);

		idxdis.close();

		FileInputStream datfis = new FileInputStream(DIR.DATA + "dat.dat");
		BufferedInputStream datbis = new BufferedInputStream(datfis);
		DataInputStream datdis = new DataInputStream(datbis);

		datdis.skipBytes((off - 10) * (Integer.SIZE / Byte.SIZE));
		while (true) {
			try {
				System.out.println(datdis.readInt());
			} catch (EOFException eof) {
				break;
			}
		}

		datdis.close();
	}

	public static void constructQuery() throws SQLException,
			ClassNotFoundException, IOException {
		DBAccess db = new DBAccess();
		ResultSet rs = db
				.executeQuery("select id from webpage order by id desc limit 1");

		int maxId = -1;
		if (rs.next()) {
			maxId = rs.getInt("id");
		} else {
			System.out.println("get max id error");
			return;
		}

		if (maxId == -1) {
			System.out.println("maxid = -1");
			return;
		}

		Map<String, Integer> idx = loadIndex(DIR.DATA + "idx");
		FileOutputStream idxfos = new FileOutputStream(DIR.DATA + "query.dat");
		BufferedOutputStream idxbos = new BufferedOutputStream(idxfos);
		DataOutputStream idxdos = new DataOutputStream(idxbos);

		int startId = -1;
		while (startId < maxId) {
			rs.close();
			rs = db.executeQuery("select id, query from webpage where id > "
					+ startId + " order by id asc limit 5000");

			while (rs.next()) {
				startId = rs.getInt("id");
				String query = rs.getString("query");
				query = query.replaceAll("[^\u4e00-\u9fa5]", "");

				if (query.isEmpty())
					continue;

				Set<String> terms = getTokens(query);
				idxdos.writeInt(terms.size());
				for (String term : terms) {
					if (idx.containsKey(term)) {
						idxdos.writeInt(idx.get(term));
					} else {
						idxdos.writeInt(-1);
					}
				}
			}
		}

		idxdos.close();
	}

	public static Set<String> getTokens(String doc) throws IOException {
		SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer(
				Version.LUCENE_31);
		StringReader reader;
		TokenStream ts;
		CharTermAttribute cta;
		reader = new StringReader(doc);
		ts = analyzer.tokenStream("content", reader);

		if (ts == null)
			return null;

		Set<String> hs = new HashSet<String>();
		cta = ts.getAttribute(CharTermAttribute.class);
		while (ts.incrementToken()) {
			hs.add(cta.toString());
		}
		return hs;
	}

	public static Map<String, Integer> loadIndex(String file)
			throws IOException {
		FileInputStream fis = new FileInputStream(file);
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		Map<String, Integer> indexer = new HashMap<String, Integer>();

		indexer.clear();
		int size = dis.readInt();
		for (int i = 0; i < size; i++) {
			int val = dis.readInt();
			int len = dis.readInt();
			byte[] bytes = new byte[len];
			for (int j = 0; j < len; j++) {
				bytes[j] = dis.readByte();
			}
			indexer.put(new String(bytes), val);
		}
		dis.close();
		return indexer;
	}

	public static void showQuery() throws IOException {
		FileInputStream fis = new FileInputStream(DIR.DATA + "query.dat");
		BufferedInputStream bis = new BufferedInputStream(fis);
		DataInputStream dis = new DataInputStream(bis);

		int total = 0;
		int max = -1;
		int min = 1000;
		int non = 0;
		while (true) {
			int len;
			try {
				len = dis.readInt();
				total++;
				if (max < len)
					max = len;
				if (min > len)
					min = len;
			} catch (EOFException eof) {
				break;
			}
			System.out.println("------ " + len);
			for (int i = 0; i < len; i++) {
				int did = dis.readInt();
				if (did == -1)
					non++;
				System.out.print(String.format("%10d", did));
			}
			System.out.println();
		}

		System.out.println("max: " + max);
		System.out.println("min: " + min);
		System.out.println("tot: " + total);
		System.out.println("non: " + non);
		dis.close();
	}

	public static void getValidQuery() {
		// FileInputStream fis = new FileInputStream(DIR.DATA + "query.dat");
		// BufferedInputStream bis = new BufferedInputStream(fis);
		// DataInputStream dis = new DataInputStream(bis);

	}
}
